﻿using System;
using System.Collections.Generic;
using System.Linq;
using DevelopTool.Bll.LocalDbBlls;
using DevelopTool.Bll.TipsBlls.Jobs;
using DevelopTool.Common;
using DevelopTool.Model.CommonModels;
using DevelopTool.Model.Enums;
using DevelopTool.Model.NoteModels;
using DevelopTool.Model.SchedulerModels;
using DevelopTool.Model.TipsModels;
using LiteDB;
using Sunny.UI;

namespace DevelopTool.Bll.TipsBlls
{
    public class TipsBll : BaseBll
    {
        public TipsBll()
        {
            using(var db = new LiteDatabase(LiteDbContext.ConnectionString))
            {
                var col = db.GetCollection<Tips>();
                col.EnsureIndex(x => x.NodeName);
                col.EnsureIndex(x => x.NodePid);
                col.EnsureIndex(x => x.NodeType);
                col.EnsureIndex(x => x.CreateTime);
                col.EnsureIndex(x => x.Id);
            }
        }


        public List<Tips> GetList(MenuNodeType nodeType = MenuNodeType.Unknown)
        {
            using(var db = new LiteDatabase(LiteDbContext.ConnectionString))
            {
                var models = db.GetCollection<Tips>().FindAll();

                if(nodeType != MenuNodeType.Unknown)
                {
                    models = models.Where(it => it.NodeType == nodeType);
                }

                return models.OrderByDescending(it => it.CreateTime).ToList();
            }
        }


        /// <summary>
        /// 根据内容关键字查询到id集合
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public List<Tips> GetListByText(string text)
        {
            using(var db = new LiteDatabase(LiteDbContext.ConnectionString))
            {
                List<Tips> noteList = new List<Tips>();

                var col = db.GetCollection<Tips>();

                var tipsIdList = col.Find(it => !string.IsNullOrEmpty(it.Text) && it.Text.GZipDecompress().IndexOf(text,StringComparison.OrdinalIgnoreCase) > -1).Select(it => it.Id).ToList();
                foreach(int tipsId in tipsIdList)
                {
                    noteList.Add(col.FindOne(it => it.Id == tipsId && it.NodeType == MenuNodeType.Node));//只查询节点，不要目录
                }

                return noteList;
            }
        }



        /// <summary>
        /// 根据id获取对象
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public Tips GetById(int id)
        {
            using(var db = new LiteDatabase(LiteDbContext.ConnectionString))
            {
                var col = db.GetCollection<Tips>();

                var tips = col.FindOne(it => it.Id == id);

                //解压缩内容
                if(!string.IsNullOrEmpty(tips.Text))
                    tips.Text = tips.Text.GZipDecompress();

                return tips;

            }
        }


        /// <summary>
        /// 保存
        /// </summary>
        /// <param name="note"></param>
        /// <returns></returns>
        public Tips Save(Tips tips)
        {
            using(var db = new LiteDatabase(LiteDbContext.ConnectionString))
            {
                var col = db.GetCollection<Tips>();

                //压缩内容
                if(!string.IsNullOrEmpty(tips.Text))
                    tips.Text = tips.Text.GZipCompress();

                tips.UpdateTime = DateTime.Now;
                col.Upsert(tips);

                //保存完后，解压缩内容
                if(!string.IsNullOrEmpty(tips.Text))
                    tips.Text = tips.Text.GZipDecompress();

                return tips;
            }
        }


        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool Delete(int id)
        {
            using(var db = new LiteDatabase(LiteDbContext.ConnectionString))
            {
                var col = db.GetCollection<Tips>();

                //查询是否有子节点，若有子节点，则不删除。
                if(col.Exists(it => it.NodePid == id)) return false;

                //删除
                var result = col.Delete(id);

                return result;
            }
        }



        /// <summary>
        /// 启动标记为运行的定时任务，用于程序启动时调用
        /// </summary>
        /// <returns></returns>
        public void StartJob()
        {
            using(var db = new LiteDatabase(LiteDbContext.ConnectionString))
            {
                var col = db.GetCollection<Tips>();
                var list = col.Find(it => it.NodeType == MenuNodeType.Node && it.IsRun && !string.IsNullOrEmpty(it.Cron)).ToList();

                foreach(Tips tips in list)
                {
                    TipsRun(tips);
                }
            }
        }


        /// <summary>
        /// 事项提醒是否正在运行
        /// </summary>
        /// <param name="scheduler"></param>
        /// <returns></returns>
        public bool IsRun(Tips tips)
        {
            return QuartzHelper.IsRun(tips.Id.ToString(),this.GetType().Name);
        }


        /// <summary>
        /// 运行事项提醒
        /// </summary>
        /// <param name="scheduler"></param>
        /// <returns></returns>
        public Tuple<bool,string> TipsRun(Tips tips)
        {
            //如果任务正在运行，那就删除重新添加
            if(IsRun(tips))
            {
                QuartzHelper.DeleteJob(tips.Id.ToString(),this.GetType().Name);
            }

            Dictionary<string,object> paramDic = new Dictionary<string,object>
                {
                    { "tips", tips }//任务参数，可以添加多个
                };
            QuartzHelper.AddCronTriggerJob(typeof(TipsJob),tips.Id.ToString(),this.GetType().Name,tips.Cron,null,null,paramDic);

            return new Tuple<bool,string>(true,"事项提醒启动成功");
        }


        /// <summary>
        /// 停止事项提醒
        /// </summary>
        /// <param name="scheduler"></param>
        /// <returns></returns>
        public Tuple<bool,string> TipsStop(Tips tips)
        {
            bool deleteResult = QuartzHelper.DeleteJob(tips.Id.ToString(),this.GetType().Name);
            return new Tuple<bool,string>(deleteResult,"事项提醒停止成功");
        }


        public void SetRemark(int id,string remark)
        {
            using(var db = new LiteDatabase(LiteDbContext.ConnectionString))
            {
                var col = db.GetCollection<Tips>();

                var model = col.FindOne(it => it.Id == id);

                model.Remark = remark;
                model.UpdateTime = DateTime.Now;

                col.Update(model);
            }
        }

        public ManageMenu Get(int id)
        {
            using(var db = new LiteDatabase(LiteDbContext.ConnectionString))
            {
                return db.GetCollection<Tips>().FindOne(it => it.Id == id);
            }
        }

    }
}
